package com.education.teacher.shiro;

import com.education.teacher.redis.RedisManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;

import java.util.Collection;
import java.util.Set;
import java.util.UUID;

/**
 * Created by lzh on 2017/8/16.
 */
public class ShareCache<K, V> implements Cache<K, V> {

    /**
     * ShareCache类需要为多例，类似与实体类
     * RedisManager 被Spring管理了 所以不能用new的形式创建对象
     * 需在构造方法中传入一个Spring管理的RedisManager 对象
     */
    private RedisManager redisManager;


    /**
     * 构造方法传入一个Spring管理的RedisManager bean
     * @param redisManager
     */
    public ShareCache(RedisManager redisManager) {
        this.redisManager = redisManager;
    }

    /**
     * 保证每个cache对象的前缀都是独立不相同的
     * clear 的时候只从redis中clear此前缀的key
     */
    private String prefix = UUID.randomUUID().toString();


    private Logger logger= LogManager.getLogger(ShareCache.class);

    @Override
    public V get(K key) throws CacheException {
        if (key == null) {
            logger.error("get[传入Key值为null]");
            return null;
        }
        logger.info("get[key="+key+"]");
        return (V) redisManager.get(prefix + key);
    }

    @Override
    public V put(K key, V value) throws CacheException {
        logger.info("put[key="+key+"]");
        V preValue = this.get(key); //接口定义要求返回之前的value
        redisManager.set(prefix + key, value);
        return preValue;
    }

    @Override
    public V remove(K key) throws CacheException {
        logger.info("remove[key="+key+"]");
        V preValue = this.get(key); //接口定义要求返回之前的value
        redisManager.delete(prefix + key);
        return preValue;
    }

    @Override
    public void clear() throws CacheException {
        if (!"".equals(prefix)){  // 前缀不为空的时候才删，避免全删了
            redisManager.deletePrefixBy(prefix);
        }
        logger.info("clear");
    }

    @Override
    public int size() {
        if (!"".equals(prefix)){
            return redisManager.getKeysNumByPrefix(prefix);
        }
        logger.error("size[prefix=空]");
        return 0;
    }

    @Override
    public Set<K> keys() {
        if (!"".equals(prefix)){
            return redisManager.getKeys(prefix);
        }
        logger.error("keys[prefix=空]");
        return null;
    }

    @Override
    public Collection<V> values() {
        if (!"".equals(prefix)){
            return redisManager.getPrefixBy(prefix);
        }
        logger.error("values[prefix=空]");
        return null;
    }
}
